home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / wais / ui / shell-ui.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  21KB  |  683 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4.  
  5.    Brewster@think.com
  6. */
  7.  
  8. /* This is a simple shell user interface for generating wprot packets.
  9.  * -brewster 7/90
  10.  *
  11.  * $Log: shell-ui.c,v $
  12.  * Revision 5.1  1992/07/10  23:13:28  curtisg
  13.  * Distributed version
  14.  *
  15.  * Revision 1.33  92/04/29  13:21:12  jonathan
  16.  * Updated for release.
  17.  * 
  18.  * Revision 1.32  92/04/09  14:19:53  morris
  19.  * now, specifying a port on the command line does a remote search on the
  20.  * local machine at the specified port.  the previous behavior was to do a
  21.  * local search, even when you specify a port.
  22.  * 
  23.  * Revision 1.31  92/03/17  14:39:28  jonathan
  24.  * modified to work with new ui scheme.
  25.  * 
  26.  * Revision 1.30  92/03/06  14:50:34  jonathan
  27.  * Correctly handle init_connection <= 0.
  28.  * 
  29.  * Revision 1.29  92/03/06  12:34:57  jonathan
  30.  * Use result of init_connection to set message length.
  31.  * 
  32.  * Revision 1.28  92/02/29  20:04:32  jonathan
  33.  * Fixed spelling of opening.
  34.  * 
  35.  * Revision 1.27  92/02/21  11:47:48  jonathan
  36.  * fixed code to re-init properly (instead of using connect_to_server).
  37.  * 
  38.  * Revision 1.26  92/02/20  16:13:15  jonathan
  39.  * Added -m for max results.
  40.  * 
  41.  * Revision 1.25  92/02/16  12:13:36  jonathan
  42.  * Added domainname to init message.
  43.  * 
  44.  *
  45.  * Important functions:
  46.  *   display_search_response
  47.  *   main
  48.  *
  49.  */
  50.  
  51. /* to do:
  52.  *  fix the number parser in view document number
  53.  *  fix if <cr> put to view document number, same as q
  54.  *  show the index again after viewing a document
  55.  *  do a 'more' type thing on viewing the doc  
  56.  *  do something to allow relevance feedback
  57.  */
  58.  
  59. #ifndef lint
  60. static char *RCSid = "$Header: /y/src/wais/wais-8-b5/ui/RCS/shell-ui.c,v 5.1 1992/07/10 23:13:28 curtisg Exp curtisg $";
  61. #endif
  62.  
  63. #include <ctype.h>
  64. #include <string.h>
  65. #include <ui.h>
  66. #include <sockets.h>
  67. #include <docid.h>
  68.  
  69. #define MAX_MESSAGE_LEN 100000
  70. #define CHARS_PER_PAGE 10000 /* number of chars retrieved in each request */
  71. #define MAX_FILE_NAME_LEN 1000
  72. #define Z39_50_SERVICE "210"
  73.  
  74. #define WAISSEARCH_DATE "Wed Apr 29 1992"
  75.  
  76. char* log_file_name = NULL;
  77. FILE* logfile = NULL;
  78.  
  79. /* modified from Jonny G's version in ui/question.c */
  80. void showDiags(d)
  81. diagnosticRecord **d;
  82. {
  83.   long i;
  84.  
  85.   for (i = 0; d[i] != NULL; i++) {
  86.     if (d[i]->ADDINFO != NULL) {
  87.       printf("Code: %s, %s\n", d[i]->DIAG, d[i] ->ADDINFO);
  88.     }
  89.   }
  90. }
  91.  
  92. /* modified from tracy shen's version in wutil.c
  93.  * displays either a text record of a set of headlines.
  94.  */
  95. void
  96. display_search_response(response)
  97. SearchResponseAPDU *response;
  98.  
  99. {
  100.   WAISSearchResponse  *info;
  101.   long continue_viewing;
  102.   long i, k;
  103.  
  104.   printf("\n Search Response:\n");
  105.  
  106.   printf("  NumberOfRecordsReturned: %d\n", 
  107.      response->NumberOfRecordsReturned); 
  108.   if ( response->DatabaseDiagnosticRecords != 0 ) {
  109.     info = (WAISSearchResponse *)response->DatabaseDiagnosticRecords;
  110.     i =0; 
  111.     continue_viewing = 1; 
  112.  
  113.     if (info->Diagnostics != NULL)
  114.       showDiags(info->Diagnostics);
  115.  
  116.     if ( info->DocHeaders != 0 ) {
  117.       k =0;
  118.       while ( (continue_viewing == 1) && info->DocHeaders[k] != 0 ) {
  119.     i++;
  120.     printf("  %2d: Score: %4ld, lines:%4ld '%s'\n", 
  121.            i, (info->DocHeaders[k]->Score),
  122.            info->DocHeaders[k]->Lines,
  123.            trim_junk(info->DocHeaders[k]->Headline));
  124.     k++;
  125.       }
  126.     }
  127.     if ( info->ShortHeaders != 0 ) {
  128.       k =0;
  129.       while ( (continue_viewing == 1) && info->ShortHeaders[k] != 0 ) {
  130.     i++;
  131.     printf("\n    ShortHeader record %2d, (can't display)", i);
  132.       }
  133.     }
  134.     if ( info->LongHeaders != 0 ) {
  135.       k =0;
  136.       while ( (continue_viewing == 1) && (info->LongHeaders[k] != 0) ) {
  137.     i++;
  138.     printf("\n    Longheader record %2d, (cant display) ", i);
  139.     /* dsply_long_hdr_record( info->LongHeaders[k++]); */
  140.       }
  141.     }
  142.     if ( info->Text != 0 ) {
  143.       k =0;
  144.       while ( (continue_viewing == 1) && (info->Text[k] != 0) ) {
  145.     i++;
  146.     printf("\n    Text record %2d, ", i);
  147.     display_text_record_completely( info->Text[k++], false);
  148.       }
  149.     }
  150.     if ( info->Headlines != 0 ) {
  151.       k =0;
  152.       while ( (continue_viewing ==1) && (info->Headlines[k] != 0) ) {
  153.     i++;
  154.     printf("\n    headline record %2d, (cant display) ", i);
  155.     /* dsply_headline_record( info->Headlines[k++]); */
  156.       }
  157.     }
  158.     if ( info->Codes != 0 ) {
  159.       k =0;
  160.       while ( (continue_viewing ==1) && (info->Codes[k] != 0) ) {
  161.     i++;
  162.     printf("\n    code record %2d, (dont knowhow to display) ", i);
  163.     /* dsply_code_record( info->Codes[k++]); */
  164.       }
  165.     }
  166.   }                /* display user info */
  167. }
  168.  
  169.  
  170.  
  171. #define MAX_KEYWORDS_LENGTH 1000
  172. #define MAX_SERVER_LENGTH 1000
  173. #define MAX_DATABASE_LENGTH 1000
  174. #define MAX_SERVICE_LENGTH 1000
  175.  
  176. void
  177. main(argc, argv)
  178. int argc;
  179. char *argv[];
  180. {
  181.   char userInfo[500];
  182.   char* request_message = NULL; /* arbitrary message limit */
  183.   char* response_message = NULL; /* arbitrary message limit */
  184.   long request_buffer_length;    /* how of the request is left */
  185.   SearchResponseAPDU  *query_response;
  186.   SearchResponseAPDU  *retrieval_response;
  187.   WAISSearchResponse  *query_info, *retrieval_info;
  188.   char keywords[MAX_KEYWORDS_LENGTH + 1];
  189.   char server_name[MAX_SERVER_LENGTH + 1];    
  190.   char service[MAX_SERVICE_LENGTH + 1];
  191.   char database[MAX_DATABASE_LENGTH + 1];
  192.   char *next_argument, *command_name;
  193.   long count, Max_Docs = 40, message_length = MAX_MESSAGE_LEN;
  194.   FILE *connection;
  195.  
  196. #ifdef THINK_C
  197.   argc = ccommand(&argv);
  198. #endif
  199.  
  200.   next_argument = next_arg(&argc, &argv);
  201.   command_name = next_argument;
  202.  
  203.   if(0 == argc){        /* no args */
  204.     printf("Usage: %s\n", command_name);
  205.     printf("       [-h host-machine]    /* defaults to localhost */\n");
  206.     printf("       [-p service-or-port] /* defaults to z39_50 */\n");
  207.     printf("       [-d database]        /* defaults to nil */\n");
  208.     printf("       [-m maximum_results] /* defaults to 40 /*\n");
  209.     printf("       [-v]                 /* print the version */\n");
  210.     printf("       word word...\n");
  211.     exit(0);
  212.   }
  213.   
  214. #ifdef THINK_C
  215.   strncpy(server_name,"wais:System Folder:wais-index:index",MAX_SERVER_LENGTH);
  216. #else
  217.   server_name[0] = '\0';  /* null it out */
  218. #endif    /* THINK_C */
  219.  
  220.   database[0] = '\0';  /* null it out */
  221.   service[0] = '\0';
  222.  
  223.   if(NULL == (next_argument = next_arg(&argc, &argv))){
  224.     printf("No arguments specified\n");
  225.     exit(0);
  226.   }
  227.   while('-' == next_argument[0]){
  228.     /* then we have an argument to process */
  229.     if(0 == strcmp("-debug", next_argument)){
  230.       logfile = stderr;
  231.     }
  232.     else if(0 == strcmp("-h", next_argument)){
  233.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  234.     printf("Expected a hostname\n");
  235.     exit(0);
  236.       }
  237.       strncpy(server_name, next_argument, MAX_SERVER_LENGTH);
  238.     }
  239.     else if((0 == strcmp("-s", next_argument)) || /* -s is for backcompatibility */
  240.         (0 == strcmp("-p", next_argument))){
  241.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  242.     printf("Expected a service name or portname\n");
  243.     exit(0);
  244.       }
  245.       strncpy(service, next_argument, MAX_SERVICE_LENGTH);
  246.     }    
  247.     else if(0 == strcmp("-d", next_argument)){
  248.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  249.     printf("Expected a database name\n");
  250.     exit(0);
  251.       }
  252.       strncpy(database, next_argument, MAX_DATABASE_LENGTH);
  253.     }
  254.     else if(0 == strcmp("-m", next_argument)){
  255.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  256.     printf("Expected a number\n");
  257.     exit(0);
  258.       }
  259.       Max_Docs = atoi(next_argument);
  260.     }
  261.     else if(0 == strcmp("-v", next_argument)){
  262.       printf("%s version: %s, %s\n",
  263.          command_name, VERSION, WAISSEARCH_DATE);
  264.     }
  265.     else{
  266.       panic("Don't recognize the %s option", next_argument);
  267.     }
  268.     if(NULL == (next_argument = next_arg(&argc, &argv))){
  269.       printf("No search words specified\n");
  270.       exit(0);
  271.     }
  272.   }
  273.   /* collect up the words for the query */
  274.   strncpy(keywords, next_argument, MAX_KEYWORDS_LENGTH);
  275.   while(NULL != (next_argument = next_arg(&argc, &argv))){
  276.     strncat(keywords, " ", MAX_KEYWORDS_LENGTH);
  277.     strncat(keywords, next_argument, MAX_KEYWORDS_LENGTH);
  278.   }
  279.     
  280.   
  281.   if (server_name[0] == '\0' && service[0] == '\0')
  282.     connection = NULL; /* do local searching */
  283.   else /* remote search, fill in defaults if necessary */
  284.    { if (server_name[0] == '\0')
  285.        gethostname(server_name,MAX_SERVER_LENGTH); /*default to local machine*/
  286.      if (service[0] == '\0')
  287.        strcpy(service, Z39_50_SERVICE); /* default */
  288.      if ((connection = connect_to_server(server_name,atoi(service))) == NULL) 
  289.       {    fprintf (stderr, "Error opening connection to %s via service %s.\n",
  290.          server_name, service);
  291.     exit(-1);
  292.       }
  293.    }
  294.  
  295.   /* init logging if we want to.  this is just for timing studies */
  296.   read_environment_variables(server_name, service);
  297.  
  298.   request_message = (char*)s_malloc((size_t)message_length * sizeof(char));
  299.   response_message = (char*)s_malloc((size_t)message_length * sizeof(char));
  300.  
  301.   {
  302.     char hostname[80];
  303.     char domainname[80];
  304.  
  305.     gethostname(hostname, 80);
  306. #ifdef M_UNIX
  307.     domainname[0] = '\0';
  308. #else
  309.     getdomainname(domainname, 80);
  310. #endif
  311. #ifdef TELL_USER
  312.     sprintf(userInfo, "waissearch %s, from host: %s.%s, user: %s",
  313.         VERSION, hostname, domainname, getenv("USER"));
  314. #else
  315.     sprintf(userInfo, "waissearch %s, from host: %s.%s", 
  316.         VERSION, hostname, domainname);
  317. #endif
  318.  
  319.     if((message_length = 
  320.     init_connection(request_message, response_message,
  321.             message_length,
  322.             connection,
  323.             userInfo)) <= 0) {
  324.       fprintf (stderr, "Error opening connection to %s via service %s.\n",
  325.            server_name, service);
  326.       exit(-1);
  327.     }
  328.   }
  329.  
  330.   while(1){        /* continue to search until the user gets tired */
  331.     request_buffer_length = message_length; /* how of the request is left */
  332.     if(NULL ==
  333.     generate_search_apdu(request_message + HEADER_LENGTH, 
  334.                  &request_buffer_length, 
  335.                  keywords, database, NULL, Max_Docs)) {
  336.       printf("Error creating search APDU: request too large");
  337.       break;
  338.     }
  339.  
  340.     if(0 ==
  341.        interpret_message(request_message, 
  342.              message_length - request_buffer_length, 
  343.              response_message,
  344.              message_length,
  345.              connection,
  346.              false    /* true verbose */
  347.              )) { /* perhaps the server shut down on us, let's see: */
  348.       if ( connection != NULL) {
  349.     fclose(connection);
  350.     if ((message_length = 
  351.           init_connection(request_message, response_message,
  352.                   message_length,
  353.                   connection,
  354.                   userInfo)) <= 0)
  355.       {
  356.         fprintf (stderr, "Error opening connection to %s via service %s.\n",
  357.              server_name, service);
  358.         exit(-1);
  359.       }
  360.     if(0 ==
  361.        interpret_message(request_message, 
  362.                  message_length - request_buffer_length, 
  363.                  response_message,
  364.                  message_length,
  365.                  connection,
  366.                  false /* true verbose */
  367.                  ))
  368.       panic("really couldn't deliver message");
  369.     }
  370.       else
  371.     panic("returned message too large");
  372.     }
  373.  
  374.     readSearchResponseAPDU(&query_response, response_message + HEADER_LENGTH);
  375.     display_search_response(query_response);
  376.     query_info = (WAISSearchResponse *)query_response->DatabaseDiagnosticRecords;
  377.  
  378.     if ( query_response->DatabaseDiagnosticRecords != 0 &&
  379.     query_info->DocHeaders !=0) {
  380.       long document_number = -1;
  381.       any* lastDocID = NULL;
  382.  
  383.       while(1){            /* keep viewing until user wants out */
  384.     while(1){        /* keep asking until we have an answer */
  385.       char document_string[1000]; /* to hold the users response */
  386.       long count;
  387.  
  388.       if(document_number>0 && 
  389.          document_number<query_response->NumberOfRecordsReturned)
  390.         lastDocID = query_info->DocHeaders[document_number-1]->DocumentID;
  391.  
  392.       printf("\nView document number [type 0 or q to quit]: ");
  393.       fflush(stdout);
  394.       fgets(document_string, 1000, stdin);
  395.       /* trim \n from string */
  396.       if(strlen(document_string) > 0)
  397.         document_string[strlen(document_string) -1] = '\0';
  398.  
  399.       if(document_string[0] == 'q'){
  400.         document_number = 0; /* signal to quit */
  401.         break;
  402.       }
  403.       if(document_string[0] == 'n'){
  404.         if(NULL == lastDocID){
  405.           printf("A document first must be selected\n");
  406.         }
  407.         else{
  408.           document_number = -3; /* signal to get next document */
  409.           break;
  410.         }
  411.       }
  412.       if(document_string[0] == 'p'){
  413.         if(NULL == lastDocID){
  414.           printf("A document first must be selected\n");
  415.         }
  416.         else{
  417.           document_number = -2; /* signal to get previous document */
  418.           break;
  419.         }
  420.       }
  421.       /* check for a number */
  422.       for(count = 0; count < strlen(document_string); count++){
  423.         if(!isdigit(document_string[count])){
  424.           document_number = -1; /* ask again */
  425.           break;        /* break out of for loop */
  426.         }
  427.       }
  428.       if (count == strlen(document_string)){
  429.         /* it is a legal number */
  430.         document_number = atol(document_string);
  431.       }
  432.       if(document_number >= 0 &&
  433.          document_number <= query_response->NumberOfRecordsReturned){
  434.         break;        /* correct entry */
  435.       }
  436.       printf("\nEntry must be a number between 0 and %ld [type 0 or q to quit] you entered \"%s\"\n", query_response->NumberOfRecordsReturned, document_string);
  437.       
  438.     }
  439.     if(document_number == 0){
  440.       break;        /* leave the viewing loop */
  441.     }
  442.     if(document_number < -1) { /* handle next and previous */
  443.       char *type;
  444.       DocObj *Doc[2];
  445.               
  446.       if(document_number == -3)
  447.         type = "WAIS_NEXT";
  448.       else if(document_number == -2)
  449.         type = "WAIS_PREV";
  450.       request_buffer_length = message_length; /* how of the request is left */
  451.       Doc[0] =
  452.         makeDocObjUsingWholeDocument(lastDocID, type);
  453.       Doc[1] = NULL;
  454.  
  455.       if(0 ==
  456.          generate_search_apdu(request_message + HEADER_LENGTH, 
  457.                   &request_buffer_length, 
  458.                   "foo", database, Doc, 1)) {
  459.         panic("request too long");
  460.       }
  461.       if(0 ==
  462.          interpret_message(request_message, 
  463.                    message_length - request_buffer_length, 
  464.                    response_message,
  465.                    message_length,
  466.                    connection,
  467.                    false /* true verbose */    
  468.                    )) { /* perhaps the server shut down on us, let's see: */
  469.         if ( connection != NULL) {
  470.           fclose(connection);
  471.           if (0 == init_connection(request_message, response_message,
  472.                        message_length,
  473.                        connection,
  474.                        userInfo))
  475.         {
  476.           fprintf (stderr, "Error opening connection to %s via service %s.\n",
  477.                server_name, service);
  478.           exit(-1);
  479.         }
  480.           if(0 ==
  481.          interpret_message(request_message, 
  482.                    message_length - request_buffer_length, 
  483.                    response_message,
  484.                    message_length,
  485.                    connection,
  486.                    false /* true verbose */
  487.                    ))
  488.         panic("really couldn't deliver message");
  489.         }
  490.         else
  491.           panic("returned message too large");
  492.       }
  493.  
  494.         readSearchResponseAPDU(&retrieval_response, 
  495.                    response_message + HEADER_LENGTH);
  496.  
  497.         retrieval_info = (WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords;
  498.  
  499.         if ( retrieval_info != NULL &&
  500.         retrieval_info->DocHeaders != NULL) {
  501.           char *type;
  502.           long size;
  503.  
  504.         lastDocID = duplicateAny(retrieval_info->DocHeaders[0]->DocumentID);
  505.         if(retrieval_info->DocHeaders[0]->Types == NULL)
  506.           type = s_strdup("TEXT");
  507.         else
  508.           type = s_strdup(retrieval_info->DocHeaders[0]->Types[0]);
  509.         printf("Headline: %s\n", 
  510.            retrieval_info->DocHeaders[0]->Headline);
  511.         size = retrieval_info->DocHeaders[0]->DocumentLength;
  512.         for(count = 0; 
  513.         count * CHARS_PER_PAGE < size;
  514.         count++){
  515.           request_buffer_length = message_length; /* how of the request is left */
  516.           if(0 ==
  517.          generate_retrieval_apdu(request_message + HEADER_LENGTH,
  518.                      &request_buffer_length, 
  519.                      lastDocID,
  520.                      CT_byte,
  521.                      count * CHARS_PER_PAGE,
  522.                      MIN((count + 1) * CHARS_PER_PAGE, size),
  523.                      type,
  524.                      database
  525.                      )) {
  526.         printf("Error generating retrieval APDU: request too long");
  527.         break;
  528.           }
  529.           if(0 ==
  530.          interpret_message(request_message, 
  531.                    message_length - request_buffer_length, 
  532.                    response_message,
  533.                    message_length,
  534.                    connection,
  535.                    false /* true verbose */    
  536.                    )) { /* perhaps the server shut down on us, let's see: */
  537.         if ( connection != NULL) {
  538.           fclose(connection);
  539.           if ((connection=connect_to_server(server_name,atoi(service))) == NULL) 
  540.             {
  541.               fprintf (stderr, "Error opening connection to %s via service %s.\n",
  542.                    server_name, service);
  543.               exit(-1);
  544.             }
  545.           if(0 ==
  546.              interpret_message(request_message, 
  547.                        message_length - request_buffer_length, 
  548.                        response_message,
  549.                        message_length,
  550.                        connection,
  551.                        false /* true verbose */
  552.                        )) {
  553.             printf("really couldn't deliver message");
  554.             break;
  555.           }
  556.         }
  557.         else {
  558.           printf("returned message too large");
  559.           break;
  560.         }
  561.           }
  562.  
  563.           readSearchResponseAPDU(&retrieval_response, 
  564.                      response_message + HEADER_LENGTH);
  565.  
  566.           /* display_search_response(retrieval_response); the general thing */
  567.           if(NULL == ((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text){
  568.         display_search_response(retrieval_response);
  569.         printf("No text was returned");
  570.         break;
  571.           }
  572.           display_text_record_completely
  573.         (((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[0], false);
  574.         }
  575.       }
  576.       freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords); 
  577.       freeSearchResponseAPDU( retrieval_response);
  578.     }
  579.     else {
  580.       printf("Headline: %s\n", 
  581.          query_info->DocHeaders[document_number - 1]->Headline);
  582.       /* we must retrieve the document in parts since it might be very long*/
  583.       for(count = 0; 
  584.           (query_info->DocHeaders[document_number - 1]->DocumentLength == 0) ||
  585.           (count * CHARS_PER_PAGE <
  586.           query_info->DocHeaders[document_number - 1]->DocumentLength);
  587.           count++){
  588.         char *type;
  589.         if(query_info->DocHeaders[document_number - 1]->Types == NULL)
  590.           type = s_strdup("TEXT");
  591.         else
  592.           type = s_strdup(query_info->DocHeaders[document_number - 1]->Types[0]);
  593.         request_buffer_length = message_length; /* how of the request is left */
  594.         if(0 ==
  595.            generate_retrieval_apdu(request_message + HEADER_LENGTH,
  596.                        &request_buffer_length, 
  597.                        query_info->DocHeaders[document_number - 1]->DocumentID, 
  598.                        CT_byte,
  599.                        count * CHARS_PER_PAGE,
  600.                        (query_info->DocHeaders[document_number - 1]->DocumentLength ? 
  601.                     MIN((count + 1) * CHARS_PER_PAGE,
  602.                         query_info->DocHeaders[document_number - 1]->DocumentLength) :
  603.                     (count + 1) * CHARS_PER_PAGE),
  604.                        type,
  605.                        database
  606.                        )) {
  607.           printf("Error generating retrieval APDU: request too long");
  608.           break;
  609.         }
  610.          
  611.         if(0 ==
  612.            interpret_message(request_message, 
  613.                  message_length - request_buffer_length, 
  614.                  response_message,
  615.                  message_length,
  616.                  connection,
  617.                  false /* true verbose */    
  618.                  )) { /* perhaps the server shut down on us, let's see: */
  619.           if ( connection != NULL) {
  620.         fclose(connection);
  621.         if ((connection=connect_to_server(server_name,atoi(service))) == NULL) 
  622.           {
  623.             fprintf (stderr, "Error opening connection to %s via service %s.\n",
  624.                  server_name, service);
  625.             exit(-1);
  626.           }
  627.         if(0 ==
  628.            interpret_message(request_message, 
  629.                      message_length - request_buffer_length, 
  630.                      response_message,
  631.                      message_length,
  632.                      connection,
  633.                      false /* true verbose */
  634.                      )) {
  635.           printf("really couldn't deliver message");
  636.           break;
  637.         }
  638.           }
  639.           else {
  640.         printf("Error deliverring message");
  641.         break;
  642.           }
  643.         }
  644.  
  645.         readSearchResponseAPDU(&retrieval_response, 
  646.                    response_message + HEADER_LENGTH);
  647.  
  648.         /* display_search_response(retrieval_response); the general thing */
  649.         if(NULL == ((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text){
  650.           display_search_response(retrieval_response);
  651.           printf("No text was returned");
  652.           break;
  653.         }
  654.         display_text_record_completely
  655.           (((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[0], false);
  656.         if(((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Diagnostics != NULL) {
  657.           showDiags(((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Diagnostics);
  658.           break;
  659.         }
  660.       }
  661.       freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords); 
  662.       freeSearchResponseAPDU( retrieval_response);
  663.     }
  664.       }
  665.     }
  666.  
  667.     freeWAISSearchResponse(query_response->DatabaseDiagnosticRecords);         
  668.     freeSearchResponseAPDU( query_response);
  669.     printf("Search for new words [type q to quit]: ");
  670.     fflush(stdout);
  671.     gets(keywords);
  672.     if(strlen(keywords) == 1 && keywords[0] == 'q'){
  673.       close_connection(connection);
  674.       break;            /* leave the asking loop */
  675.     }
  676.   }
  677.  
  678.   s_free(request_message);
  679.   s_free(response_message);
  680.  
  681.   exit(0);
  682. }
  683.